#include "./../inc/list.h"

#include <string.h>
#include <stdio.h>
#include <memory.h>
#include <stdlib.h>

typedef struct _LIST_NODE
{
	void* element;
	struct _LIST_NODE *next;
	struct _LIST_NODE *last;
}LIST_NODE;

typedef struct _LIST
{
	int size;
	int elememtSize;
	LIST_NODE *head, *tail;

	UFO_List handle;
}LIST;

UFO_List ufoListCreate(int elementSize)
{
	LIST *pList = malloc(sizeof(LIST));
	memset(pList, 0, sizeof(LIST));
	pList->elememtSize = elementSize;
	pList->handle = (UFO_List)ufoCreateHandle(UFO_ID_LIST, pList);

	return pList->handle;
}

int ufoListGetSize(UFO_List list)
{
	LIST *pList = ufoObjectFromHandle((UFO_Handle)list);
	if (pList) {
		return pList->size;
	}
	return 0;
}

int ufoListPushBack(UFO_List list, void* element)
{
	LIST *pList = ufoObjectFromHandle((UFO_Handle)list);
	if (pList && element) {
		if (!pList->head) {
			pList->tail = pList->head = malloc(sizeof(LIST_NODE));
			memset(pList->head, 0, sizeof(LIST_NODE));
			pList->head->element = malloc(pList->elememtSize);
			memcpy(pList->head->element, element, pList->elememtSize);

		}
		else {
			LIST_NODE *pCur = malloc(sizeof(LIST_NODE));
			memset(pCur, 0, sizeof(LIST_NODE));
			pCur->element = malloc(pList->elememtSize);
			memcpy(pCur->element, element, pList->elememtSize);

			pList->tail->next = pCur;
			pCur->last = pList->tail;
			pList->tail = pCur;
		}
		pList->size++;
		return 1;
	}
	return 0;
}

UFO_List_Iteartor ufoListBegin(UFO_List list)
{
	LIST *pList = ufoObjectFromHandle((UFO_Handle)list);
	if (pList) {
		return (UFO_List_Iteartor)(pList->head);
	}
	return 0;
}

UFO_List_Iteartor ufoListIteartorForward(UFO_List_Iteartor iteartor)
{
	LIST_NODE *pNode = (LIST_NODE *)iteartor;
	if (pNode) {
		return (UFO_List_Iteartor)pNode->next;
	}
	return 0;
}

UFO_List_Iteartor ufoListIteartorBackward(UFO_List_Iteartor iteartor)
{
	LIST_NODE *pNode = (LIST_NODE *)iteartor;
	if (pNode) {
		return (UFO_List_Iteartor)pNode->last;
	}
	return 0;
}

void* ufoListGetElement(UFO_List_Iteartor iteartor)
{
	LIST_NODE *pNode = (LIST_NODE *)iteartor;
	if (pNode) {	
		return pNode->element;
	}
	return 0;
}